<template>
	<div class="cl-chat-message" v-loading="!visible && loading" element-loading-text="消息加载中">
		<div
			class="cl-chat-message__scroller scroller1"
			ref="scroller"
			:style="{
				opacity: visible ? 1 : 0
			}"
		>
			<!-- 加载更多 -->
			<div class="cl-chat-message__more" v-show="list.length > 0">
				<el-button round size="mini" v-if="!nomore" :loading="loading" @click="onLoadmore">
					加载更多
				</el-button>
				<el-button v-if="nomore" type="text" style="cursor: auto;" disabled>
					没有更多了
				</el-button>
			</div>

			<!-- 消息列表 -->
			<div class="cl-chat-message__list">
				<cl-empty v-if="isSessionSys && !list.length" tips="暂无通知" />
				<template v-for="item in list">
					<sys-msg-item v-if="isSessionSys" :item="item" :key="item.id || item.uid" />
					<template v-else>
						<user-msg-item
							:item="item"
							:key="item.id || item.uid"
							@content-click="onTap(item)"
						/>
					</template>
				</template>
				<!-- 音频 -->
				<div class="voice">
					<audio style="display: none" ref="voice" :src="voice.url" controls />
				</div>
			</div>
		</div>
	</div>
</template>

<script>
import dayjs from "dayjs";
import { mapGetters, mapActions } from "vuex";
import { last, isNumber } from "cl-admin/utils";
import eventBus from "../utils/event-bus";
// import chatDB from "../utils/db";
import logo from "@/assets/logo/logo.png";
import UserMsgItem from "./user-msg-item";
import SysMsgItem from "./sys-msg-item";

export default {
	name: "chat-message",
	components: {
		UserMsgItem,
		SysMsgItem
	},
	inject: ["chat"],
	data() {
		return {
			loading: false,
			visible: false,
			pagination: {
				page: 1,
				size: 20,
				total: 0
			},
			nomore: false,
			voice: {
				url: "",
				timer: null
			},
			refreshRd: null
		};
	},

	filters: {
		duration(val) {
			return Math.ceil((val || 1) / 1000);
		}
	},

	computed: {
		...mapGetters(["userInfo", "session", "messageList"]),
		isSessionSys() {
			return this.session?.type == "system";
		},
		list() {
			let date = "";
			return this.messageList.map(e => {
				let created_at = dayjs(
					isNumber(e.created_at) ? e.created_at * 1000 : e.created_at
				).format("YYYY-MM-DD HH:mm:ss");
				// 时间间隔
				e._date = date
					? dayjs(created_at).isBefore(dayjs(date).add(1, "minute"))
						? ""
						: created_at
					: created_at;
				// 发送时间
				date = created_at;
				// 解析昵称
				// const nickName = e.type == 0 ? this.userInfo.user_name : this.session.cca_name;
				const nickName = e.reader_type == 1 ? "我" : this.session?.cca_name;
				// 解析头像
				const avatar =
					e.reader_type == 1 ? this.userInfo.avatarUrl : this.session?.cca_avatar;
				if (this.isSessionSys) {
					return e;
				}
				return {
					...e,
					avatar: avatar || logo,
					nickName,
					mode: this.chat.modes[e.content_type]
				};
			});
		}
	},

	beforeCreate() {
		// 销毁事件
		eventBus.$off("message.refresh");
		eventBus.$off("message.scrollToBottom");
	},

	created() {
		if (this.session) {
			this.visible = true;
		}
		// 监听列表刷新
		eventBus.$on("message.refresh", this.refresh);

		// 滚动到底部
		eventBus.$on("message.scrollToBottom", this.scrollToBottom);
	},

	destroyed() {
		// 清除播放
		clearTimeout(this.voice.timer);
		this.messageList.map(e => {
			e.isPlay = false;
		});
	},

	methods: {
		...mapActions(["putSession", "putLastMsg"]),
		// 点击
		onTap(item) {
			// 播放语音
			if (item.mode == "voice") {
				this.messageList.forEach(e => {
					this.$set(e, "isPlay", e.id == item.id ? e.isPlay : false);
				});
				item.isPlay = !item.isPlay;
				if (item.isPlay) {
					this.voice.url = item.content ?? "";
					this.$nextTick(() => {
						this.$refs.voice.play();
					});
				} else {
					this.$refs.voice.pause();
					item.isPlay = false;
				}
				clearTimeout(this.voice.timer);
				this.voice.timer = setTimeout(() => {
					item.isPlay = false;
				}, item?.duration ?? 1000);
			}
		},

		// 刷新列表
		refresh(params) {
			// 请求随机值
			const rd = (this.refreshRd = Math.random());
			// 请求参数
			const data = {
				...this.pagination,
				...params,
				cr_id: this.session.cr_id
			};
			const { type } = this.session || {};
			// 加载动画
			this.loading = true;
			// 首页处理
			if (data.page === 1) {
				this.visible = false;
				this.$store.commit("CLEAR_MESSAGE_LIST");
			}

			if (type == "system") {
				this.getOaRefund(data, rd);
				return;
			}
			this.$service.chats
				.recordList(data)
				.then(async res => {
					// 防止脏数据
					if (rd != this.refreshRd) {
						return false;
					}
					this.$store.commit("SET_SESSION_ID", res.cc_id);
					let msglist = (res.record_list || []).map(v => ({
						...v,
						content_type: v.type
					}));
					// chatDB.setRecords(msglist);
					this.nomore = msglist.length < data.size;
					// 分页信息
					// this.pagination = res.pagination;
					// 追加数据
					this.$store.commit("PREPEND_MESSAGE_LIST", msglist);

					if (data.page === 1) {
						this.scrollToBottom();
						// 首次滚动隐藏
						setTimeout(this.apiDone, 0);
						if (msglist.length > 0) {
							let msg = last(msglist);
							// await chatDB.putLastMsg(data.cr_id, msg, false);
							this.putLastMsg({ cr_id: data.cr_id, msg, updated: false });
						}
					} else {
						this.apiDone();
					}
				})
				.catch(err => {
					// this.$message.error(err);
					this.apiDone();
				});
		},
		// 加载更多
		onLoadmore() {
			this.refresh({ page: this.pagination.page + 1 });
		},
		getOaRefund(params, rd) {
			let data = {
				...params,
				work_flow_type: 1, // 审批流类型 1:退款审批流
				biz_id: "",
				bra_id: "", // 品牌id
				store_id: "", // 门店id
				name: "", // 客户名称
				time: [], // 发起时间
				start_time: "",
				end_time: "",
				finish_time: [], // 完成时间
				finish_start_time: "",
				finish_end_time: "",
				status: "", // 状态
				oa_status: 0, // oa列表类型 0:全部 1: 待处理 2:已处理（未完成） 3:完成
				is_new: 1
			};
			this.$service.oa
				.page(data)
				.then(async res => {
					// 防止脏数据
					if (rd != this.refreshRd) {
						return false;
					}
					let msglist = (res.list || []).map(v => ({
						...v,
						msg_type: "oa"
					}));
					// chatDB.setRecords(msglist);
					this.nomore = msglist.length < data.size;
					// 分页信息
					// this.pagination = res.pagination;
					// 追加数据
					this.$store.commit("PREPEND_MESSAGE_LIST", msglist);

					if (data.page === 1) {
						this.scrollToBottom();
						// 首次滚动隐藏
						setTimeout(this.apiDone, 10);
						if (msglist.length > 0) {
							let msg = last(msglist);
							// await chatDB.putLastMsg(data.cr_id, msg, false);
							this.putLastMsg({ cr_id: data.cr_id, msg, updated: false });
						}
					} else {
						this.apiDone();
					}
				})
				.catch(err => {
					// this.$message.error(err);
					this.apiDone();
				});
		},
		// 请求完成
		apiDone() {
			this.loading = false;
			this.visible = true;
		},
		// 滚动到底部
		scrollToBottom(behavior) {
			this.$nextTick(() => {
				this.$refs?.scroller?.scrollTo({
					top: 999_9999,
					behavior: behavior ? behavior : this.visible ? "smooth" : "auto"
				});
			});
		}
	}
};
</script>

<style lang="scss" scoped>
.cl-chat-message {
	height: calc(100% - 5px);
	overflow: hidden;
	margin-bottom: 5px;

	&__scroller {
		height: calc(100% - 10px);
		border-radius: 5px;
		margin: 5px 0px 5px 5px;
		padding: 10px;
		box-sizing: border-box;
	}

	&__more {
		display: flex;
		justify-content: center;
		margin-bottom: 20px;
	}

	::v-deep &__item {
		margin-bottom: 20px;

		.date {
			text-align: center;
			margin: 10px 0;

			span {
				background-color: #dadada;
				font-size: 12px;
				color: #fff;
				border-radius: 3px;
				padding: 3px 5px 2px 5px;
				letter-spacing: 1px;
			}
		}

		.main {
			display: flex;

			.avatar {
				flex-shrink: 0;

				img {
					display: block;
					height: 40px;
					width: 40px;
					border-radius: 3px;
					background-color: #fff;
				}
				::v-deep.cl-avatar {
					background-color: #fff;
				}
			}

			.det {
				display: flex;
				flex-direction: column;
				max-width: 60%;

				.name {
					margin-bottom: 5px;
				}

				.content {
					display: inline-block;
					border-radius: 8px;
					box-sizing: border-box;
					font-size: 12px;
				}
			}
		}

		&.is-left {
			.main {
				.det {
					margin-left: 10px;
					align-items: flex-start;

					.content {
						border-top-left-radius: 0;
						background-color: #fff;
					}
				}
			}

			&.is-voice {
				.content {
					justify-content: flex-start;
				}
			}
		}
	}
}
</style>
